class Cart {
  constructor() {
    this.res()
    this.checkLogin();
    this.getData();
    this.bindEve();
  }
  //1- 绑定全部事件的方法
  bindEve() {
    // 全选按钮绑定点击事件
    this.$('.cart-th input').addEventListener('click', this.allCheck.bind(this));
    // 商品共同父级绑定事件,实现委托
    this.$('.cart-list').addEventListener('click', this.dispatch.bind(this))   //不能使用call必须要用bind
    this.$('.cart-list').addEventListener('input', this.Modify.bind(this))            //非input框也可以委托input事件
  }
    //2-渲染购物车列表
    async getData() {
      let userId = localStorage.getItem('user_id');
      //获取到token直接赋值给Authorization字段
      axios.defaults.headers.common['Authorization'] = localStorage.getItem('token');
      let res = await axios.get('http://localhost:8888/cart/list?id=' + userId);
      let { status, data }=res;
      // 判断服务器状态
      if (status != 200) throw new Error("当你看到我的时候证明你眼睛有点不好使!");
      // 判断token是否过期
      if (data.code == 0) {
        //过期跳转登录页面
        location.assign('./login.html?returnUrl=./cart.html');
      }
      if (data.code == 1) {
        // 渲染购物车列表数据
        let html = '';
        data.cart.map(ele => {
          html += `<ul class="goods-list yui3-g" data-id=${ele.goods_id}>
          <li class="yui3-u-3-8 pr">
              <input type="checkbox" class="good-checkbox">
              <div class="good-item">
                  <div class="item-img">
                      <img src="${ele.img_small_logo}">
                  </div>
                  <div class="item-msg">${ele.title}</div>
              </div>
          </li>
          <li class="yui3-u-1-8">
          </li>
          <li class="yui3-u-1-8">
              <span class="price">${ele.current_price}</span>
          </li>
          <li class="yui3-u-1-8">
              <div class="clearfix">
                  <a href="javascript:;" class="increment mins">-</a>
                  <input autocomplete="off" type="text" value="${ele.cart_number}" minnum="1" class="itxt">
                  <a href="javascript:;" class="increment plus">+</a>
              </div>
              <div class="youhuo">有货</div>
          </li>
          <li class="yui3-u-1-8">
              <span class="sum">${ele.current_price * ele.cart_number}</span>
          </li>
          <li class="yui3-u-1-8">
              <div class="del1">
                  <a href="javascript:;" class="del-goods">删除</a>
              </div>
              <div>移到我的关注</div>
          </li>
      </ul>`;
        });
        // 追加到页面中
        this.$('.cart-list').innerHTML = html;
      }
    }
    //3- 全选和单选
  allCheck(eve) {
    // 获取全选的状态 
    console.log(eve.target);
    let status = eve.target.checked;
    //调用单选属性传递参数
    this.setOneCheck(status)
    // 统计数量价格
    this.totalSP();
  }
  //4- 设置单个商品的状态
  setOneCheck(status) {
    let oneGoods = document.querySelectorAll('.good-checkbox');
    // 单个商品的状态跟随全选状态
    oneGoods.forEach(ev => {
      ev.checked = status;
    })
  } 
 //5-1 区分操作
  dispatch(v) {
    let str =v.target;
    if (str.classList.contains('good-checkbox')) {
      //传输当前点击的节点对象
      this.oneChick(str);
      //统计数量和价格
      this.totalSP();
    }
    // 判断点击的是否为删除
    if (str.classList.contains('del-goods')) {
      this.delGoods(str)
    }
    //判断点击是+ 还是-
    if(str.classList.contains('plus')||str.classList.contains('mins')){
      //传递事件委托
      this.Modify(v);
    }
  }
//6-1 单个商品点击时的状态
  oneChick(str) {
    console.log(str, str.checked);
    // 随机商品取消,全选取消
    if (!str.checked) {
      this.$('.cart-th input').checked = false;
    }else{
      //全选框选中
      let oneGoods = document.querySelectorAll('.good-checkbox');
      oneGoods=Array.from(oneGoods);
      if(oneGoods.every((v)=>v.checked))this.$('.cart-th input').checked = true;
     //价格总计改变
    }
  }

//7-1 统计数量和价格
  totalSP() {
    // 只统计选中的数量和价格
    let goodsList = document.querySelectorAll('.goods-list');
        // 数量和小计的累加
        let tNum = 0;
        let tPrice = 0
    goodsList.forEach(ul => {

      let checkbox = this.getChildren(ul, '.good-checkbox', 'checked');
      if (checkbox) {
        tNum += this.getChildren(ul, '.itxt', 'value') -0;
        tPrice +=this.getChildren(ul, '.sum', 'innerHTML') -0;
        console.log(tPrice);
      }
    })
    console.log(tNum);

    // 设置到页面中
    this.$('.sumprice-top strong').innerHTML = tNum;
    this.$('.summoney span').innerHTML = tPrice.toFixed(2);
  }
  //7-2 封装获取父节点下子节点和属性方法
  getChildren(father, children, attr = 'value') {
    return father.querySelector(children)[attr];
  }

//8-1 删除商品
  delGoods(tar) { 
      let redayDel = this.deep(tar);
      //改变this指向
      let that = this;
      layer.msg('要删除吗老铁?', {
        time: 10000, //20s后自动关闭
        btn: ['删除', '取消'],
        yes(index) {
          layer.close(index);
          // 获取商品id和用户id,删除ul
          let userId = localStorage.getItem('user_id');
          let token = localStorage.getItem('token');
          let goodsId = redayDel.dataset.id;
          //携带token
          axios.defaults.headers.common['Authorization'] = token;
          //发送删除请求
          axios.get('http://localhost:8888/cart/remove?id=' + userId + '&goodsId=' + goodsId).then(({ status, data }) => {
            // 判断服务器状态和接口状态
            if (status == 200 && data.code == 1) {
              // 删除商品
              redayDel.remove();
              // 获取当前商品是否选中,决定是否调用价格同价的方法
              that.getChildren(redayDel, '.good-checkbox', 'checked') && that.totalSP();
            }
            //如果全部商品删除那么全选不勾选,这里一定要写到then异步里等删除操作执行完进行判断
            let goodsList=document.querySelector('.goods-list');
            if(!goodsList){
              document.querySelector('#allcheck').checked=false;
            }
          });
          // console.log($('.goods-list'));
          // console.log(document.querySelector('#allcheck').checked);
        }
      });
    }
  //8-2 递归找父级
  deep(ele, tar = 'ul') {
    if (ele.nodeName == tar.toUpperCase()) {
      return ele;
    }
    //结果返回到上面
    return this.deep(ele.parentNode)
  }
  res() {
    // 添加响应拦截器
    axios.interceptors.response.use(function (response) {
      // 对响应数据做点什么
      // console.log(response);
      if (response.data.code == 401) {
        location.assign('./login.html?returnUrl=./cart.html')
      }
      return response;
    }, function (error) {
      // 对响应错误做点什么
      return Promise.reject(error);
    });
  }


//9-1商品数量增加
Modify(eve) {
  // 判断当前操作的是否为输入框
  if (eve.target.type == 'checkbox') return;
  // console.log(eve);
  // 根据事件类型区分当前是输入和点击操作
  // console.log(eve.target);
  // console.log(eve.type);
  let input = '';
  let val = 0;
  if (eve.type == 'click') {
    // 判断当前点击的为+,还是-
    let mark = eve.target.innerHTML;
    if (mark == '+') {
      input = eve.target.previousElementSibling;
      val = input.value - 0 + 1
    }
    if (mark == '-') {
      // 获取input框
      input = eve.target.nextElementSibling;
      // 修改数量
      val = input.value - 1
      // 数量小于1,则设置为1
      if (val < 1) val = 1;
    }
    input.value = val;
  }
  if (eve.type == 'input') {
    val=eve.target.value;
  }
  this.sumPrice(val, eve.target)
}
//9-2 小计的更新
sumPrice(num, target) {
  // 找到最大父级ul
  let ul = this.deep(target);
  // 获取单价
  let price = this.getChildren(ul, '.price', 'innerHTML');
  let sum = ul.querySelector('.sum');
  // 保留两位小数
  sum.innerHTML = (num * price).toFixed(2)
  // 发送ajax,修改服务器商品数量
  let goodsId = ul.dataset.id;
  this.sendAjaxNum(goodsId, num);
  // 计算总价
  this.totalSP()
}

//10-1 添加防抖
times = '';
sendAjaxNum(goodsId, num) {
  clearTimeout(this.times);
  this.times = setTimeout(() => {
    axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
    axios.defaults.headers.common['Authorization'] = localStorage.getItem('token');
    let userId = localStorage.getItem('user_id');
    // 对参数编码
    let param = `goodsId=${goodsId}&number=${num}&id=${userId}`;
    axios.post('http://localhost:8888/cart/number', param).then(res => {
      // console.log(res);
    })
  }, 300)


}



  /*****验证是否登录*******/
  checkLogin() {
    const TOKEN = localStorage.getItem('token');
    if (!TOKEN) location.assign('./login.html?./cart.html');
  }






  $(ele) {
    let res = document.querySelectorAll(ele);
    return res.length == 1 ? res[0] : res;
  }
}

new Cart;